﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;

namespace CjcPhotoPrint
{
	public class Transformable : DependencyObject, INotifyPropertyChanged
	{
		public static DependencyProperty SelectedProperty = DependencyProperty.Register(
			"Selected",
			typeof( bool ),
			typeof( Transformable ) );

		public BindingList<TransformationContext> Transformations { get; private set; }

		public Transformable()
		{
			var original = new IdentityContext( this, null, "Original" );
			var final = new IdentityContext( this, original, "Final" );

			final.PropertyChanged += OnPropertyChanged;

			Transformations = new BindingList<TransformationContext>() { original, final };
			Transformations.ListChanged += delegate { OnPropertyChanged( "Drawing" ); };

			CollectionViewSource.GetDefaultView( Transformations ).MoveCurrentToLast();

			Selected = false;
		}

		public virtual string Name { get { return null; } }

		public bool Selected
		{
			get { return (bool)GetValue( SelectedProperty ); }
			set { SetValue( SelectedProperty, value ); }
		}

		public virtual Drawing BaseDrawing
		{
			get { return null; }
		}

		public Drawing Drawing
		{
			get { return ( Transformations.Count > 0 ) ? Transformations.Last().Drawing : null; }
		}

		public double AspectRatio
		{
			get { return ( Transformations.Count > 0 ) ? Transformations.Last().AspectRatio : 1; }
		}

		/// <summary>
		/// Inserts a transformation.
		/// </summary>
		/// <param name="parent">The parent transformation.</param>
		/// <param name="transform">The transformation to add.</param>
		/// <returns></returns>
		public TransformationContext InsertTransformation( TransformationContext parent, Transformation transformation )
		{
			var context = new TransformationContext( this, parent, transformation );
			var insertIndex = Transformations.IndexOf( parent ) + 1;

			if ( insertIndex < Transformations.Count ) Transformations[ insertIndex ].Parent = context;

			Transformations.Insert( insertIndex, context );

			return context;
		}

		public void RemoveTransformation( TransformationContext context )
		{
			var removeIndex = Transformations.IndexOf( context );

			if ( removeIndex < Transformations.Count - 1 ) Transformations[ removeIndex + 1 ].Parent = context.Parent;
			context.Parent = null;

			Transformations.RemoveAt( removeIndex );
		}

		#region INotifyPropertyChanged Members

		public event PropertyChangedEventHandler PropertyChanged;

		protected void OnPropertyChanged( object sender, PropertyChangedEventArgs e )
		{
			OnPropertyChanged( "Drawing" );
		}

		public void OnPropertyChanged( string propertyName )
		{
			if ( PropertyChanged != null ) PropertyChanged( this, new PropertyChangedEventArgs( propertyName ) );
		}

		#endregion
	}
}